# -*- coding: utf-8 -*-
"""
4.1 LangServe：快速部署 LangChain 应用 - Python 服务器代码示例

本文件是一个使用 LangServe 将简单的 LangChain 链部署为 REST API 的示例服务器。

运行步骤:
1.  确保已安装必要库:
    `pip install "langchain[serve]" python-dotenv` 
    (或者 `pip install langchain langserve fastapi uvicorn sse-starlette python-dotenv`)
2.  确保项目根目录下或当前目录有 `.env` 文件，并包含 `OPENAI_API_KEY`。
3.  激活 Python 虚拟环境。
4.  在终端中运行 FastAPI/Uvicorn 服务器:
    `uvicorn 6-大模型应用开发.LangChain.04-Advanced_Deployment.4_1_LangServe:app --reload --port 8000`
    (请根据你的实际文件路径调整 `6-大模型应用开发.LangChain.04-Advanced_Deployment.4_1_LangServe:app`)
5.  服务器启动后，可以在浏览器访问:
    *   `http://localhost:8000` (根路径)
    *   `http://localhost:8000/docs` (API 文档)
    *   `http://localhost:8000/cold-joke/playground/` (LangServe Playground)
6.  可以使用 requests 或 RemoteRunnable 调用 API。
"""

from fastapi import FastAPI
from langserve import add_routes
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from dotenv import load_dotenv
import uvicorn # 用于在脚本内直接启动 (可选)

# 加载 .env 文件中的环境变量 (例如 OPENAI_API_KEY)
load_dotenv()
print("环境变量已加载。")

# --- 1. 定义你的 LangChain Runnable 对象 --- 
print("\n--- 1. 定义 LangChain Runnable --- ")
prompt = ChatPromptTemplate.from_template("讲一个关于 {topic} 的冷笑话")
model = ChatOpenAI(model="gpt-3.5-turbo")
# 简单的 LCEL 链
chain = prompt | model | StrOutputParser()
print("冷笑话链定义完成。")

# --- 2. 创建 FastAPI 应用实例 --- 
print("\n--- 2. 创建 FastAPI 应用 --- ")
app = FastAPI(
    title="LangChain 冷笑话服务",
    version="1.0",
    description="一个使用 LangServe 部署的简单 LangChain 应用",
)
print("FastAPI 应用创建成功。")

# --- 3. 使用 add_routes 将 Runnable 添加到 FastAPI 应用 --- 
print("\n--- 3. 使用 LangServe 添加路由 --- ")
add_routes(
    app,
    chain,             # 你要部署的 LangChain Runnable 对象
    path="/cold-joke",  # 指定 API 的基础路径
    # 可以选择性地为 Playground 定义输入示例
    playground_type="default",
    enable_feedback_endpoint=True, # 开启反馈端点 (需要 LangSmith 配置)
    enable_public_trace_link_endpoint=True # 开启公共追踪链接端点 (需要 LangSmith 配置)
)
print(f"已将链添加到路径 /cold-joke")

# --- (可选) 添加额外的自定义路由 --- 
@app.get("/")
def read_root():
    return {"message": "欢迎来到 LangChain 冷笑话服务! 前往 /cold-joke/playground/ 测试 API。"}

# --- (可选) 在脚本内直接启动 Uvicorn 服务器 --- 
# 通常推荐在命令行使用 uvicorn server:app --reload 来启动
if __name__ == "__main__":
    print("\n--- (可选) 在脚本内启动 Uvicorn --- ")
    print("访问 http://localhost:8000")
    # 注意：如果使用这种方式启动，可能需要调整 uvicorn 命令中的路径
    # 例如，如果直接运行此文件 `python 4.1_LangServe.py`
    # uvicorn.run("__main__:app", host="localhost", port=8000, reload=True)
    # 但通常还是建议在命令行启动: uvicorn 4.1_LangServe:app --reload
    uvicorn.run(app, host="localhost", port=8000)

print("\nLangServe 服务器脚本定义完毕。请使用 uvicorn 运行。")
